﻿
/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2/26/2011
 * Time: 2:56 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;

namespace TomatoSynchronizer
{
	public class ObjectDictionary<T> : IDictionary<string, object>
	{
		public ObjectDictionary(T instance)
		{
			this.instance = instance;
		}

		public static implicit operator T (ObjectDictionary<T> source)
		{
			return source.instance;
		}

		public static implicit operator ObjectDictionary<T> (T source)
		{
			return source.AsDictionary();
		}

		private T instance;

		#region IDictionary<string,object> Members

		public void Add(string key, object value)
		{
			throw new NotImplementedException();
		}

		public bool ContainsKey(string key)
		{
			return typeof(T).GetProperty(key) != null;
		}

		public ICollection<string> Keys
		{
			get { return typeof(T).GetProperties().Select(p => p.Name).ToArray(); }
		}

		public bool Remove(string key)
		{
			throw new NotImplementedException();
		}

		public bool TryGetValue(string key, out object value)
		{
			var p = typeof(T).GetProperty(key);
			if (p == null)
			{
				value = null;
				return false;
			}
			else
			{
				value = p.GetValue(instance, null);
				return true;
			}
		}

		public ICollection<object> Values
		{
			get { return typeof(T).GetProperties().Select(p => p.GetValue(instance, null)).ToArray(); }
		}

		public object this[string key]
		{
			get
			{
				object result = null;
				if (TryGetValue(key, out result))
					return result;
				else
					throw new Exception(string.Format("Property not found: {0}", key));
			}
			set
			{
				object result = null;
				if (TryGetValue(key, out result))
					result = value;
				else
					throw new Exception(string.Format("Property not found: {0}", key));
			}
		}

		#endregion

		#region ICollection<KeyValuePair<string,object>> Members

		public void Add(KeyValuePair<string, object> item)
		{
			throw new NotImplementedException();
		}

		public void Clear()
		{
			throw new NotImplementedException();
		}

		public bool Contains(KeyValuePair<string, object> item)
		{
			throw new NotImplementedException();
		}

		public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
		{
			throw new NotImplementedException();
		}

		public int Count
		{
			get { return typeof(T).GetProperties().Length; }
		}

		public bool IsReadOnly
		{
			get { return true; }
		}

		public bool Remove(KeyValuePair<string, object> item)
		{
			throw new NotImplementedException();
		}

		#endregion

		#region IEnumerable<KeyValuePair<string,object>> Members

		public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
		{
			var q =
				from p in typeof(T).GetProperties()
				select new KeyValuePair<string, object>(p.Name, p.GetValue(instance, null));
			return q.GetEnumerator();
		}

		#endregion

		#region IEnumerable Members

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	#endregion
	
	public static class ObjectDictionaryExtensions
	{
		public static ObjectDictionary<T> AsDictionary<T>(this T instance)
		{
			return new ObjectDictionary<T>(instance);
		}
	}

}